// webpack中import引法会报错
const path = require('path')
const glob = require('glob')    // 扫描文件
const uglify = require('uglifyjs-webpack-plugin')   // 代码压缩插件
const htmlPlugin = require('html-webpack-plugin')  // html文件打包插件
const extractTextPlugin = require('extract-text-webpack-plugin')    // css打包分离插件
const PurifyCSSPlugin = require('purifycss-webpack')    // 消除未使用到的css
const entry = require('./webpack_config/entry_webpack.js')
const webpack = require('webpack')
const copyWebpackPlugin= require('copy-webpack-plugin') // 拷备静态资源

console.log(encodeURIComponent(process.env.type))   // node语法
// 配置开发环境和生产环境
// package.json => win系统：set type=dev&webpack || mac os系统：export type=dev&&webpack
// node语法：process.env 接收来自package.json文件：scripts/set type
if (process.env.type === 'build') {
    // 生产环境
    var website = {
        publicPath: 'http://jspang.com:1717/'
    }
} else {
    // 开发环境
    var website = {
        publicPath: 'http://192.168.1.14:1717/'
    }
}

module.exports = {
    /**
     * 开发调式工具：devtool，项目正式上线打包需要删除此配置项。
     * 浏览器报错机制：error:29:23 => 错误:行:列(字符)
     * source-map：应用于复杂而较大的项目。打包速度较慢，会生成详细的独立map文件。内容包含对应代码行、代码列。
     * cheap-moudle-source-map：精简模式source-map。内容不包含代码列。
     * eval-source-map：应用于2~3个月左右的小项目。不会生成独立map，直接生成到出口js文件代码中。速度快但缺乏安全性，对项目性能也会有一定影响。内容包含对应代码行、代码列。
     * cheap-moudle-eval-source-map：精简模式seval-source-map。内容不包含代码列。
     */
    devtool: 'cheap-moudle-eval-source-map',
    // 入口
    entry: {    // entry名称固定
        entry: './src/entry.js',    // entry名称随意取
        // entry2: './src/entry2.js'
        jquery: 'jquery',    // 插离jquery类库，需在entry中建立入口路径 jquery: 此处 jquery 名称是个变量，随意取。
        vue: 'vue'  // 分享vue,先引入vue到入口文件。
    },
    // 旧↑，新↓；提取entry进行模块化
    // entry: entry.path,
    // 出口
    output: {
        path: path.resolve(__dirname, 'dist'),   // 路径
        filename: '[name].js',
        publicPath: website.publicPath  // 公用路径设置处
    },
    // 模块
    module: {
        // rules规则
        rules: [
            {
                test: /\.css$/, // 正则表达式，找到css文件
                // extractTextPlugin插件要求：改造
                use: extractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [{
                        loader: 'css-loader',
                        options: { importLoaders: 1 }
                    }, {
                        loader: 'postcss-loader'
                    }]
                })
                // use: [{
                //     loader: 'style-loader'
                // }, {
                //     loader: 'css-loader'
                // }]
                // 写法1：use: ['style-loader', 'css-loader'],    // 用哪个包来处理它们
                // 写法2：loader: ['style-loader', 'css-loader'] => 同use: []
                // 写法3：对象型 => use: [{ loader: 'style-loader' }, { loader: 'css-loader' }]
                // include：可选参数，哪些文件需要处理；exclude：对应参数，哪些文件不需要处理。
                // query: 可靠参数，loader额外配置项。
            }, {
                test: /\.(png|jpg|gif)/,    // 正则表达式，匹配图片
                use: [{
                    loader: 'url-loader',   // 注意：loader是不需要引入的，只有插件才需要引入
                    options: {
                        limit: 5,   // 固定单位：b => 当图片大于这个数就生成路径，小于就生成base64
                        outputPath: 'images/' // 打包图片至指定路径文件夹下
                    }
                    // file-loader 拷备图片同步图片名问题
                }]
            }, {
                test: /\.(htm|html)$/i,
                use: ['html-withimg-loader']
            }, {
                test: /\.(less$)/,
                // 注意user里的顺序，不可乱
                // use: [{
                //     loader: 'style-loader'
                // }, {
                //     loader: 'css-loader'
                // }, {
                //     loader: 'less-loader'
                // }],
                // extractTextPlugin插件要求：改造并加入less分离
                use: extractTextPlugin.extract({
                    use: [{
                        loader: 'css-loader'
                    }, {
                        loader: 'less-loader'
                    }],
                    fallback: 'style-loader'
                })
            }, {
                test: /\.scss/,
                // use: [{
                //     loader: 'style-loader'
                // }, {
                //     loader: 'css-loader'
                // }, {
                //     loader: 'sass-loader'
                // }]
                // extractTextPlugin插件要求：改造并加入sass分离
                use: extractTextPlugin.extract({
                    use: [{
                        loader: 'css-loader'
                    }, {
                        loader: 'sass-loader'
                    }],
                    fallback: 'style-loader'
                })
            }, {
                test: /\.(jsx|js)$/,    // 正则中：$代表结尾
                use: {
                    loader: 'babel-loader'
                    // options：选择；presets：渲染器
                    // #方法1：
                    // options: {
                    //     presets: [ 'es2015', 'react' ]
                    // }
                    // #方法2：自动读取同目录下的/.babelrc/文件，官方固定文件命名。
                },
                exclude: /node_modules/ // 不转换node_modules文件夹下的js和jsx
            }
        ]
    },
    // 插件
    plugins: [
        // optimize优化.Commons（共同）Chunk（块）Plugin：抽离入口文件、类库等其它文件。优化和便于管理js代码
        new webpack.optimize.CommonsChunkPlugin({
            /**
            // 插离单个类库
            name: 'jquery', // 对应入口文件的jquery(41行)
            filename: 'assets/js/jquery.min.js',   // 抽离到文件路径，注意：filename非驼峰格式。非必填：默认到根目录下。
            minChunks: 2    // 最少需要抽离出几个文件，通常为2个文件。通常：一个入口文件，一个其它文件
             */
            // 变更：插离多个类库
            name: [ 'jquery', 'vue' ],
            filename: 'assets/js/[name].js',  // 会根据上面的name来进行文件取名, ext代表扩展名
            minChunks: 2
        }),
        // providePlugin 装备(提供插件)，webpack自带插件。好处：类库通过providePlugin引入，全局中未使用装不会被打包进来。
        new webpack.ProvidePlugin({
            $: 'jquery' // 抽离jquery类库，独立出jquery文件。参：41入品文件配置项。参：CommonsChunkPlugin插件，抽离类库插件配置项。
            // vue: 'vue'
            // ...
        }),
        // new uglify(),    // 代码压缩减少文件容量
        new htmlPlugin({
            // 压缩
            minify: {
                removeAttributeQuotes: true // 去掉html中id="title"中的"引号
            },
            hash: true, // 去js缓存
            template: './src/index.html'    // 模版：html的相对路径

        }),
        new extractTextPlugin('css/index.css'), // 注意各种搞脑子的路径问题，这里在某种条件下删除了/css前的/
        // 消除未使用到的css
        new PurifyCSSPlugin({
            paths: glob.sync(path.join(__dirname, 'src/*.html'))    // webpack打包的时候去比对html文件中所有的标签、id、class，在css中没有用到标签、id、class样式消除
        }),
        // 添加版权所有插件
        new webpack.BannerPlugin('JSPang版权所有，看官方免费视频到jspang.com观看'),
        // 拷备静态资源：注册此插件声明不同之处([{}])
        new copyWebpackPlugin([{
            from: __dirname + '/src/public',    // from：取自哪里！__dirname：webpack语法，代表本地目录的意思
            to: './public'  // 复制到哪里！因为在出口处 output。path中设置了path.resolve(__dirname, 'dist')路径（行49），所以这里不需要拼接__dirname路径
        }]),
        // 在热更新devServer(行191)，无法生效或生效缓慢时，需要用到此插件，内部暂时无需配置。
        new webpack.HotModuleReplacementPlugin()
    ],
    // 配置webpack开发服务，启用热更新
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),   // 要服务哪里的代码
        host: '192.168.1.14',    // 配置运行ip
        compress: true, // 服务器是否压缩
        port: 1717    // 端口
    },
    // 自动打包配置项：ctrl+s 时触发，因编辑器会自动保存，任何修改都会自动打包。
    watchOptions: {
        poll: 1000, // 监测时间：每1000毫秒监测一次项目是否做过修改
        aggregateTimeout: 500, // 超时：输入结束状态判断，类似搜索的即输即查，判断输入结束，停顿500毫秒再进行搜索。
        ignored: /node_modules/ // 不监听node_modules文件夹下内容
    }
}
